
package org.cleverframe.fastdfs.utils;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.cleverframe.fastdfs.pool.FTPConnectionPool;
import org.cleverframe.fastdfs.pool.FtpClientPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class FileUploader {

    private static final String REMOTE_BASE_DIR = "/data/ftp"; // 替换为远程服务器上的目标目录
    private static FTPConnectionPool ftpClientPool;
    private static final Logger log = LoggerFactory.getLogger(FileUploader.class);
    static {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxTotal(10); // 最大连接数
        config.setMaxIdle(5); // 最大空闲连接数
        config.setMinIdle(2); // 最小空闲连接数
//        ftpClientPool = new FtpClientPool(config);

        ftpClientPool = new FTPConnectionPool(10);

    }

    /**
     * 获取当前日期的日志文件名。
     * @return 当前日期的日志文件名
     */
    public static String getLogFileNameForDate() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDateTime.now().format(formatter);
    }

    /**
     * 将字节数组形式的文件上传到FTP服务器。
     * @param fileBytes 文件字节数组
     * @param remoteFileName 远程文件名
     * @param envDir 环境目录
     */
    public static void uploadFileToFtpServer(byte[] fileBytes, String remoteFileName, String envDir,String message) {
        FTPClient ftpClient = null;
        try {
//            ftpClient = ftpClientPool.borrowFtpClient();
            ftpClient = ftpClientPool.borrowObject();
            System.out.println("Uploading file to: " + remoteFileName);

            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
            }
            // 创建远程目录
            String remoteDirPath = REMOTE_BASE_DIR + "/" + envDir + "/" + getLogFileNameForDate();
            System.out.println("remoteDirPath---->:" + remoteDirPath);

            createRemoteDirectories(ftpClient, remoteDirPath);
            ftpClient.changeWorkingDirectory(remoteDirPath);

            uploadFileFTP(ftpClient,remoteFileName,fileBytes);
            //同时上传写入日志
            String logFileName = "log_"+getLogFileName();
            log.info("开始写入日志文件...");
            uploadFileFTP(ftpClient,logFileName,message.getBytes());


        } catch (Exception ex) {
            log.error(ex.getMessage());
        } finally {
            if (ftpClient != null) {
//                ftpClientPool.returnFtpClient(ftpClient);
                ftpClientPool.returnObject(ftpClient);
            }
        }
    }

    public static void uploadFileToFtpServerWith2Log(String message,  String envDir) {

        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            // 创建远程目录
            String remoteDirPath = REMOTE_BASE_DIR + "/" + envDir + "/" + getLogFileNameForDate();
            createRemoteDirectories(ftpClient, remoteDirPath);
            ftpClient.changeWorkingDirectory(remoteDirPath);
            //记录操作日志
            String logFileName = "log_"+getLogFileName();
            uploadFileFTP(ftpClient,logFileName,message.getBytes());
        } catch (Exception ex) {
            log.error(ex.getMessage());
        } finally {
            if (ftpClient != null) {
                ftpClientPool.returnObject(ftpClient);
            }
        }
    }

    private static void uploadFileFTP(FTPClient ftpClient, String remoteFileName, byte[] fileBytes) throws IOException {

        try (InputStream inputStream = new ByteArrayInputStream(fileBytes)) {
            boolean done = uploadFile(ftpClient,remoteFileName, inputStream);
            if (done) {
                System.out.println("The file is uploaded successfully.");
            } else {
                System.out.println("Failed to upload the file.");
            }
        }

    }

    private static String getCurrentTime() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.now().format(formatter);
    }

    private static  String getLogFileName() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDateTime.now().format(formatter) + ".txt";
    }


    private static void createRemoteDirectories(FTPClient ftpClient, String remoteDirPath) throws IOException {
        // 确保路径以斜杠开头
        if (!remoteDirPath.startsWith("/")) {
            remoteDirPath = "/" + remoteDirPath;
        }
        String[] directories = remoteDirPath.split("/");
        StringBuilder currentDir = new StringBuilder();
        for (String dir : directories) {
            if (!dir.isEmpty()) {
                currentDir.append("/").append(dir);
                try {
                    if (!ftpClient.changeWorkingDirectory(currentDir.toString())) {
                        if (!ftpClient.makeDirectory(currentDir.toString())) {
                            throw new IOException("Could not create directory: " + currentDir);
                        }
                        ftpClient.changeWorkingDirectory(currentDir.toString());
                    }
                } catch (IOException e) {
                    throw new IOException("Error accessing or creating directory: " + currentDir, e);
                }
            }
        }
    }


   /* private static void createRemoteDirectories(FTPClient ftpClient, String remoteDirPath) throws IOException {
        String[] directories = remoteDirPath.split("/");
        StringBuilder currentDir = new StringBuilder();
        for (int i = 1; i < directories.length; i++) {
            if (!directories[i].isEmpty()) {
                currentDir.append("/").append(directories[i]);
                if (!ftpClient.changeWorkingDirectory(currentDir.toString())) {
                    if (!ftpClient.makeDirectory(currentDir.toString())) {
                        throw new IOException("Could not create directory: " + currentDir);
                    }
                }
            }
        }
    }*/

    /**
     * 上传文件到FTP服务器。
     * @param ftpClient FTP客户端
     * @param remoteFileName 远程文件名
     * @param inputStream 输入流
     * @return 上传是否成功
     * @throws IOException 如果上传失败
     */
    private static boolean uploadFile(FTPClient ftpClient, String remoteFileName, InputStream inputStream) throws IOException {
        if (remoteFileName.startsWith("log_")) {
            return ftpClient.appendFile(remoteFileName, inputStream);
        } else {
            return ftpClient.storeFile(remoteFileName, inputStream);
        }
    }
}